﻿using Koala.Pro.Core;

namespace Koala.Pro.Common
{
    public static class EntityHelper
    {
        public static bool IsEntity(Type type)
        {
            return ReflectionHelper.IsAssignableToGenericType(type, typeof(IEntity<>));
        }

        public static bool IsEntityWithId(Type type)
        {
            Type[] interfaces = type.GetInterfaces();
            foreach (Type type2 in interfaces)
            {
                if (type2.GetTypeInfo().IsGenericType && type2.GetGenericTypeDefinition() == typeof(IEntity<>))
                {
                    return true;
                }
            }
            return false;
        }

        public static bool HasDefaultId<TKey>(IEntity<TKey> entity)
        {
            if (EqualityComparer<TKey>.Default.Equals(entity.Id, default(TKey)))
            {
                return true;
            }
            if (typeof(TKey) == typeof(int))
            {
                return Convert.ToInt32(entity.Id) <= 0;
            }
            if (typeof(TKey) == typeof(long))
            {
                return Convert.ToInt64(entity.Id) <= 0;
            }
            return false;
        }

        public static Type GetPrimaryKeyType<TEntity>()
        {
            return GetPrimaryKeyType(typeof(TEntity));
        }

        public static Type GetPrimaryKeyType(Type entityType)
        {
            Type[] interfaces = entityType.GetTypeInfo().GetInterfaces();
            foreach (Type type in interfaces)
            {
                if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IEntity<>))
                {
                    return type.GenericTypeArguments[0];
                }
            }
            throw new Exception("Can not find primary key type of given entity type: " + entityType?.ToString() + ". Be sure that this entity type implements IEntity<TPrimaryKey> interface");
        }

        public static object GetEntityId(object entity)
        {
            if (!ReflectionHelper.IsAssignableToGenericType(entity.GetType(), typeof(IEntity<>)))
            {
                throw new Exception(entity.GetType()?.ToString() + " is not an Entity !");
            }
            return ReflectionHelper.GetValueByPath(entity, entity.GetType(), "Id");
        }
    }
}
